package com.cloud.netty.codec;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelPipeline;
import io.netty.util.CharsetUtil;

/*
* 说明
* 1.我们自定义一个handler 需要继续netty 规定好的某个handlerAdapter(规范)
* 2.这时我们自定义一个handler，才能成为一个handler
* */
public class NettyServerHandler extends ChannelInboundHandlerAdapter {


    /** 读取实际数据（这里我们可以读取各个客户端发送的消息）
     * 1.channelHandlerContext 上下文对象，含有管道pipeline，通道channel，地址
     * 2.Object msg：客户端发送的数据，以对象的形式接收
     * */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        super.channelRead(ctx, msg);
        // 现在拿到数据是在缓冲中，如果我们需要进行处理的话，需要进行转换
//        System.out.println("server ctx = " + ctx);
        // 将msg转成一个ByteBuf 这里这个ByteBuf是netty的，不是nio中，且性能更强些
//        ByteBuf byteBuf = (ByteBuf) msg;
//        System.out.println("客户端发送的消息是："+byteBuf.toString(CharsetUtil.UTF_8));
//        System.out.println("客户端地址是：" + ctx.channel().remoteAddress());

        // 通道和管道的对比 相互包含的关系
//        Channel channel = ctx.channel();
        // 本质是一个双向链表，涉及到出入栈
//        ChannelPipeline pipeline = ctx.pipeline();
        // 服务器端和客户端都是Java
        StudentPOJO.Student student = (StudentPOJO.Student)msg;
        System.out.println("客户端发送的数据："+student.getId() +" "+ student.getName());
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        // 数据写入到缓冲区，并刷新
        // 一般讲，我们对发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端~",CharsetUtil.UTF_8));
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 出现异常需要关闭通道
        ctx.close();
    }
}
